import copy
import os
import allure
from core.rest_client import RestClient
from utils.assert_util import AssertUtil
from utils.extract_util import ExtractUtil


class ExecuteTestCase:
    def __init__(self):
        self.session = RestClient
        self.extract = ExtractUtil
        self.file_path = os.path.join(os.path.dirname(os.path.dirname(os.path.realpath(__file__))), "data", "file/")

    def execute_test_case(self, test_data, access_token=None):
        """
        获取接口请求入参信息，后续新增字段在此补充
        :param test_data: 从yaml测试数据文件读取的数据
        :param access_token: 默认None，接口需要访问令牌认证时需要传入
        :return:
        """
        # 测试用例的入口对数据进行深拷贝
        test_data = copy.deepcopy(test_data)
        # request_info 部分信息
        # url = test_data['request_info']['url']
        url = self.extract.extract_url(test_data['request_info']['url'])  # url 中带可变id 时候处理
        method = test_data['request_info']['method']
        headers = test_data['request_info']['headers']
        allure_case_title = test_data['request_info']['case_title']
        allure_case_description = test_data['request_info']['case_description']
        # 配置 allure 动态 title description
        allure.dynamic.title(allure_case_title)
        allure.dynamic.description(allure_case_description)

        # 获取case_info ,里面可能是 params json data
        case_info = test_data['case_info']
        # if case_info['params']:
        if 'params' in case_info and case_info['params']:
            if access_token:  # access_token 传的时候才加入 params
                case_info['params'].update(access_token)
        else:
            case_info['params'] = access_token
        # 获取 validate 校验信息
        validate = case_info.pop("validate", None)
        # 获取 extract，json表达式，需要提取的数据，从当前接口返回提取，用于下一个接口关联
        extract = case_info.pop("extract", None)
        # 对 case_info 有 ${xx} 的数据处理
        case_info = self.extract.extract_case(case_info)
        # 文件上传处理
        file, files = case_info.pop('files', None), None
        if file is not None:
            for fk, fv in file.items():
                # files={'media': ('filename.jpg', open(file_path, 'rb'), 'application/octet-stream')}
                files = {fk: (fv, open(self.file_path + fv, 'rb'), 'application/octet-stream')}
        response = self.session.do_request(url=url, method=method, headers=headers, files=files, **case_info)
        # 根据 extract的json表达式 提取返回值中的数据 并写入 extract.yaml
        self.extract.extract_data(response, extract)
        if validate:
            AssertUtil.validate_response(response, validate)
        return response


ExecuteTestCase = ExecuteTestCase()
